bitkeeper revision 1.1389.5.21 (427a5ee3rBlRFupS4xBvv_nWVHQlsA)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 5 May 2005 17:58:59 +0000 (17:58 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 5 May 2005 17:58:59 +0000 (17:58 +0000)
Clean up IO-APIC handling in domain0, and the hypercall interface
exported by Xen (inc. removal of PCI-related calls). This hopefully
fixes acpi=off.
Signed-off-by: Keir Fraser <keir@xensource.com>
22 files changed:
.rootkeys
linux-2.6.11-xen-sparse/arch/xen/i386/kernel/apic.c
linux-2.6.11-xen-sparse/arch/xen/i386/kernel/io_apic.c
linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io_apic.h [deleted file]
tools/libxc/xc_physdev.c
xen/arch/ia64/domain.c
xen/arch/ia64/xenmisc.c
xen/arch/ia64/xensetup.c
xen/arch/x86/domain.c
xen/arch/x86/io_apic.c
xen/arch/x86/physdev.c [new file with mode: 0644]
xen/common/Makefile
xen/common/dom0_ops.c
xen/common/domain.c
xen/common/physdev.c [deleted file]
xen/drivers/char/serial.c
xen/include/asm-x86/config.h
xen/include/asm-x86/physdev.h [new file with mode: 0644]
xen/include/public/dom0_ops.h
xen/include/public/physdev.h
xen/include/xen/physdev.h [deleted file]
xen/include/xen/sched.h

index 5bfc5e18248e9afa44dd2999c6392bac3ed3c77d..cfb01fda7dfd935c703c8781c2de4d24751f3484 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 4118b6a418gnL6AZsTdglC92YGqYTg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/highmem.h
 42539fb5A9hsS3NFQ-2VY4y1TONZZQ linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/hypercall.h
 40f5623aJVXQwpJMOLE99XgvGsfQ8Q linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io.h
-42778a69MXZVxch4pQqYsMPS0WnNSg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io_apic.h
 40f5623aKXkBBxgpLx2NcvkncQ1Yyw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h
 40f5623aDMCsWOFO0jktZ4e8sjwvEg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h
 40f5623arsFXkGdPvIqvFi3yFXGR0Q linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h
 41aaf567a36esU-rUK7twPiv-yTFyw xen/arch/x86/mtrr/mtrr.h
 41aaf567DcTL6pqVtLZJI5cSryyA1A xen/arch/x86/mtrr/state.c
 3f12cff65EV3qOG2j37Qm0ShgvXGRw xen/arch/x86/nmi.c
+4051bcecFeq4DE70p4zGO5setf47CA xen/arch/x86/physdev.c
 3ddb79bc7KxGCEJsgBnkDX7XjD_ZEQ xen/arch/x86/rwlock.c
 3ddb79bcrD6Z_rUvSDgrvjyb4846Eg xen/arch/x86/setup.c
 405b8599xI_PoEr3zZoJ2on-jdn7iw xen/arch/x86/shadow.c
 41a61536SZbR6cj1ukWTb0DYU-vz9w xen/common/multicall.c
 3ddb79bdD4SLmmdMD7yLW5HcUWucXw xen/common/page_alloc.c
 3e54c38dkHAev597bPr71-hGzTdocg xen/common/perfc.c
-4051bcecFeq4DE70p4zGO5setf47CA xen/common/physdev.c
 3ddb79bdHqdQpATqC0rmUZNbsb6L6A xen/common/resource.c
 40589968dD2D1aejwSOvrROg7fOvGQ xen/common/sched_bvt.c
 3e397e6619PgAfBbw2XFbXkewvUWgw xen/common/schedule.c
 41a61536MFhNalgbVmYGXAhQsPTZNw xen/include/asm-x86/multicall.h
 3ddb79c3xjYnrv5t3VqYlR4tNEOl4Q xen/include/asm-x86/page.h
 3ddb79c3ysKUbxZuwKBRK3WXU2TlEg xen/include/asm-x86/pci.h
+42422fb0FVX-TJkSvAXnbfwMf19XFA xen/include/asm-x86/physdev.h
 3ddb79c2QF5-pZGzuX4QukPCDAl59A xen/include/asm-x86/processor.h
 40cf1596bim9F9DNdV75klgRSZ6Y2A xen/include/asm-x86/regs.h
 3ddb79c2plf7ciNgoNjU-RsbUzawsw xen/include/asm-x86/rwlock.h
 3ddb79c0MOVXq8qZDQRGb6z64_xAwg xen/include/xen/pci_ids.h
 3e54c38dlSCVdyVM4PKcrSfzLLxWUQ xen/include/xen/perfc.h
 3e54c38de9SUSYSAwxDf_DwkpAnQFA xen/include/xen/perfc_defn.h
-42422fb0FVX-TJkSvAXnbfwMf19XFA xen/include/xen/physdev.h
 3ddb79c04nQVR3EYM5L4zxDV_MCo1g xen/include/xen/prefetch.h
 3e4540ccU1sgCx8seIMGlahmMfv7yQ xen/include/xen/reboot.h
 40589969nPq3DMzv24RDb5LXE9brHw xen/include/xen/sched-if.h
index 4ca346bc4923ac3b6193c70382f22d319d721e47..5f071a59569e21226893c42931449024638ff38f 100644 (file)
 
 #include <linux/config.h>
 #include <linux/init.h>
-#include <asm/apic.h>
 
+#include <linux/mm.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/kernel_stat.h>
+#include <linux/sysdev.h>
+
+#include <asm/atomic.h>
+#include <asm/smp.h>
+#include <asm/mtrr.h>
+#include <asm/mpspec.h>
+#include <asm/desc.h>
+#include <asm/arch_hooks.h>
+#include <asm/hpet.h>
+
+#include <mach_apic.h>
+
+#include "io_ports.h"
+
+/*
+ * Debug level
+ */
 int apic_verbosity;
 
 int get_physical_broadcast(void)
@@ -49,5 +73,11 @@ void ack_bad_irq(unsigned int irq)
  */
 int __init APIC_init_uniprocessor (void)
 {
+#ifdef CONFIG_X86_IO_APIC
+       if (smp_found_config)
+               if (!skip_ioapic_setup && nr_ioapics)
+                       setup_IO_APIC();
+#endif
+
        return 0;
 }
index 667d11e10b38adbf4d8057f13c40af8630f33e04..6fbaa196132c54f4958db06cb758b2a403d62311 100644 (file)
 #include <asm/smp.h>
 #include <asm/desc.h>
 #include <asm/timer.h>
-#include <asm/io_apic.h>
-#include <asm/apic.h>
 
 #include <mach_apic.h>
 
 #include "io_ports.h"
 
-int (*ioapic_renumber_irq)(int ioapic, int irq);
-atomic_t irq_mis_count;
+#ifdef CONFIG_XEN
+
+#include <asm-xen/xen-public/xen.h>
+#include <asm-xen/xen-public/physdev.h>
+
+/* Fake i8259 */
+#define make_8259A_irq(_irq)     (io_apic_irqs &= ~(1UL<<(_irq)))
+#define disable_8259A_irq(_irq)  ((void)0)
+#define i8259A_irq_pending(_irq) (0)
 
 unsigned long io_apic_irqs;
 
+static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
+{
+       physdev_op_t op;
+       int ret;
+
+       op.cmd = PHYSDEVOP_APIC_READ;
+       op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
+       op.u.apic_op.offset = reg;
+       ret = HYPERVISOR_physdev_op(&op);
+       if (ret)
+               return ret;
+       return op.u.apic_op.value;
+}
+
+static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
+{
+       physdev_op_t op;
+
+       op.cmd = PHYSDEVOP_APIC_WRITE;
+       op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
+       op.u.apic_op.offset = reg;
+       op.u.apic_op.value = value;
+       HYPERVISOR_physdev_op(&op);
+}
+
+#define io_apic_read(a,r)    xen_io_apic_read(a,r)
+#define io_apic_write(a,r,v) xen_io_apic_write(a,r,v)
+
+#endif /* CONFIG_XEN */
+
+int (*ioapic_renumber_irq)(int ioapic, int irq);
+atomic_t irq_mis_count;
+
 static DEFINE_SPINLOCK(ioapic_lock);
 
 /*
@@ -111,6 +149,7 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin)
        entry->pin = pin;
 }
 
+#ifndef CONFIG_XEN
 /*
  * Reroute an IRQ to a different pin.
  */
@@ -247,6 +286,9 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
        }
        spin_unlock_irqrestore(&ioapic_lock, flags);
 }
+#else
+#define clear_IO_APIC() ((void)0)
+#endif
 
 #if defined(CONFIG_IRQBALANCE)
 # include <asm/processor.h>    /* kernel_thread() */
@@ -668,9 +710,7 @@ static inline void move_irq(int irq) { }
 #ifndef CONFIG_SMP
 void fastcall send_IPI_self(int vector)
 {
-#if 1
-       return;
-#else
+#ifndef CONFIG_XEN
        unsigned int cfg;
 
        /*
@@ -686,7 +726,6 @@ void fastcall send_IPI_self(int vector)
 }
 #endif /* !CONFIG_SMP */
 
-
 /*
  * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
  * specific CPU-side IRQs.
@@ -752,6 +791,7 @@ static int find_irq_entry(int apic, int pin, int type)
        return -1;
 }
 
+#ifndef CONFIG_XEN
 /*
  * Find the pin to which IRQ[irq] (ISA) is connected
  */
@@ -774,6 +814,7 @@ static int find_isa_irq_pin(int irq, int type)
        }
        return -1;
 }
+#endif
 
 /*
  * Find a specific PCI IRQ entry.
@@ -821,6 +862,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
        return best_guess;
 }
 
+#ifndef CONFIG_XEN
 /*
  * This function currently is only a helper for the i386 smp boot process where 
  * we need to reprogram the ioredtbls to cater for the cpus which have come online
@@ -844,6 +886,7 @@ void __init setup_ioapic_dest(void)
 
        }
 }
+#endif /* !CONFIG_XEN */
 
 /*
  * EISA Edge/Level control register, ELCR
@@ -1133,7 +1176,7 @@ static inline int IO_APIC_irq_trigger(int irq)
 }
 
 /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
-u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 };
+u8 irq_vector[NR_IRQ_VECTORS]; /* = { FIRST_DEVICE_VECTOR , 0 }; */
 
 int assign_irq_vector(int irq)
 {
@@ -1157,6 +1200,7 @@ int assign_irq_vector(int irq)
        return current_vector;
 }
 
+#ifndef CONFIG_XEN
 static struct hw_interrupt_type ioapic_level_type;
 static struct hw_interrupt_type ioapic_edge_type;
 
@@ -1172,20 +1216,19 @@ static inline void ioapic_register_intr(int irq, int vector, unsigned long trigg
                        irq_desc[vector].handler = &ioapic_level_type;
                else
                        irq_desc[vector].handler = &ioapic_edge_type;
-#if 0
                set_intr_gate(vector, interrupt[vector]);
-#endif
        } else  {
                if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
                                trigger == IOAPIC_LEVEL)
                        irq_desc[irq].handler = &ioapic_level_type;
                else
                        irq_desc[irq].handler = &ioapic_edge_type;
-#if 0
                set_intr_gate(vector, interrupt[irq]);
-#endif
        }
 }
+#else
+#define ioapic_register_intr(_irq,_vector,_trigger) ((void)0)
+#endif
 
 void __init setup_IO_APIC_irqs(void)
 {
@@ -1241,7 +1284,7 @@ void __init setup_IO_APIC_irqs(void)
                else
                        add_pin_to_irq(irq, apic, pin);
 
-               if (!apic && !IO_APIC_IRQ(irq))
+               if (/*!apic &&*/ !IO_APIC_IRQ(irq))
                        continue;
 
                if (IO_APIC_IRQ(irq)) {
@@ -1249,10 +1292,8 @@ void __init setup_IO_APIC_irqs(void)
                        entry.vector = vector;
                        ioapic_register_intr(irq, vector, IOAPIC_AUTO);
                
-#if 0
                        if (!apic && (irq < 16))
                                disable_8259A_irq(irq);
-#endif
                }
                spin_lock_irqsave(&ioapic_lock, flags);
                io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
@@ -1268,6 +1309,7 @@ void __init setup_IO_APIC_irqs(void)
 /*
  * Set up the 8259A-master output pin:
  */
+#ifndef CONFIG_XEN
 void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
 {
        struct IO_APIC_route_entry entry;
@@ -1275,9 +1317,7 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
 
        memset(&entry,0,sizeof(entry));
 
-#if 0
        disable_8259A_irq(0);
-#endif
 
        /* mask LVT0 */
        apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
@@ -1308,9 +1348,7 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
        io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
-#if 0
        enable_8259A_irq(0);
-#endif
 }
 
 static inline void UNEXPECTED_IO_APIC(void)
@@ -1489,7 +1527,6 @@ static void print_APIC_bitfield (int base)
 
 void /*__init*/ print_local_APIC(void * dummy)
 {
-#if 0
        unsigned int v, ver, maxlvt;
 
        if (apic_verbosity == APIC_QUIET)
@@ -1569,7 +1606,6 @@ void /*__init*/ print_local_APIC(void * dummy)
        v = apic_read(APIC_TDCR);
        printk(KERN_DEBUG "... APIC TDCR: %08x\n", v);
        printk("\n");
-#endif
 }
 
 void print_all_local_APICs (void)
@@ -1609,6 +1645,9 @@ void /*__init*/ print_PIC(void)
        v = inb(0x4d1) << 8 | inb(0x4d0);
        printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
 }
+#else
+void __init print_IO_APIC(void) { }
+#endif /* !CONFIG_XEN */
 
 static void __init enable_IO_APIC(void)
 {
@@ -1650,7 +1689,7 @@ void disable_IO_APIC(void)
         */
        clear_IO_APIC();
 
-#if 0
+#ifndef CONFIG_XEN
        disconnect_bsp_APIC();
 #endif
 }
@@ -1662,7 +1701,7 @@ void disable_IO_APIC(void)
  * by Matt Domsch <Matt_Domsch@dell.com>  Tue Dec 21 12:25:05 CST 1999
  */
 
-#ifndef CONFIG_X86_NUMAQ
+#if !defined(CONFIG_XEN) && !defined(CONFIG_X86_NUMAQ)
 static void __init setup_ioapic_ids_from_mpc(void)
 {
        union IO_APIC_reg_00 reg_00;
@@ -1769,6 +1808,7 @@ static void __init setup_ioapic_ids_from_mpc(void)
 static void __init setup_ioapic_ids_from_mpc(void) { }
 #endif
 
+#ifndef CONFIG_XEN
 /*
  * There is a nasty bug in some older SMP boards, their mptable lies
  * about the timer IRQ. We do the following to work around the situation:
@@ -1826,13 +1866,11 @@ static unsigned int startup_edge_ioapic_irq(unsigned int irq)
        unsigned long flags;
 
        spin_lock_irqsave(&ioapic_lock, flags);
-#if 0
        if (irq < 16) {
                disable_8259A_irq(irq);
                if (i8259A_irq_pending(irq))
                        was_pending = 1;
        }
-#endif
        __unmask_IO_APIC_irq(irq);
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
@@ -1995,6 +2033,7 @@ static struct hw_interrupt_type ioapic_level_type = {
        .end            = end_level_ioapic,
        .set_affinity   = set_ioapic_affinity,
 };
+#endif /* !CONFIG_XEN */
 
 static inline void init_IO_APIC_traps(void)
 {
@@ -2024,17 +2063,18 @@ static inline void init_IO_APIC_traps(void)
                         * so default to an old-fashioned 8259
                         * interrupt if we can..
                         */
-#if 0
                        if (irq < 16)
                                make_8259A_irq(irq);
+#ifndef CONFIG_XEN
                        else
-#endif
                                /* Strange. Oh, well.. */
                                irq_desc[irq].handler = &no_irq_type;
+#endif
                }
        }
 }
 
+#ifndef CONFIG_XEN
 static void enable_lapic_irq (unsigned int irq)
 {
        unsigned long v;
@@ -2081,9 +2121,7 @@ static void setup_nmi (void)
         */ 
        apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ...");
 
-#if 0
        on_each_cpu(enable_NMI_through_LVT0, NULL, 1, 1);
-#endif
 
        apic_printk(APIC_VERBOSE, " done.\n");
 }
@@ -2158,7 +2196,6 @@ static inline void unlock_ExtINT_logic(void)
  */
 static inline void check_timer(void)
 {
-#if 0
        int pin1, pin2;
        int vector;
 
@@ -2265,8 +2302,10 @@ static inline void check_timer(void)
        printk(" failed :(.\n");
        panic("IO-APIC + timer doesn't work!  Boot with apic=debug and send a "
                "report.  Then try booting with the 'noapic' option");
-#endif
 }
+#else
+#define check_timer() ((void)0)
+#endif
 
 /*
  *
@@ -2293,7 +2332,7 @@ void __init setup_IO_APIC(void)
         */
        if (!acpi_ioapic)
                setup_ioapic_ids_from_mpc();
-#if 0
+#ifndef CONFIG_XEN
        sync_Arb_IDs();
 #endif
        setup_IO_APIC_irqs();
@@ -2417,6 +2456,7 @@ device_initcall(ioapic_init_sysfs);
 
 int __init io_apic_get_unique_id (int ioapic, int apic_id)
 {
+#ifndef CONFIG_XEN
        union IO_APIC_reg_00 reg_00;
        static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
        physid_mask_t tmp;
@@ -2445,7 +2485,6 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id)
                apic_id = reg_00.bits.ID;
        }
 
-#if 0
        /*
         * Every APIC in a system must have a unique ID or we get lots of nice 
         * 'stuck on smp_invalidate_needed IPI wait' messages.
@@ -2481,10 +2520,10 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id)
                if (reg_00.bits.ID != apic_id)
                        panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic);
        }
-#endif
 
        apic_printk(APIC_VERBOSE, KERN_INFO
                        "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
+#endif /* !CONFIG_XEN */
 
        return apic_id;
 }
@@ -2555,12 +2594,10 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
                mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq,
                edge_level, active_high_low);
 
-#ifndef CONFIG_XEN
        ioapic_register_intr(irq, entry.vector, edge_level);
 
        if (!ioapic && (irq < 16))
                disable_8259A_irq(irq);
-#endif
 
        spin_lock_irqsave(&ioapic_lock, flags);
        io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1));
diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io_apic.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io_apic.h
deleted file mode 100644 (file)
index bc10fff..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-#ifndef __ASM_IO_APIC_H
-#define __ASM_IO_APIC_H
-
-#include <linux/config.h>
-#include <asm/types.h>
-#include <asm/mpspec.h>
-
-#include <asm-xen/xen-public/xen.h>
-#include <asm-xen/xen-public/physdev.h>
-
-/*
- * Intel IO-APIC support for SMP and UP systems.
- *
- * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar
- */
-
-#ifdef CONFIG_X86_IO_APIC
-
-#ifdef CONFIG_PCI_MSI
-static inline int use_pci_vector(void) {return 1;}
-static inline void disable_edge_ioapic_vector(unsigned int vector) { }
-static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
-static inline void end_edge_ioapic_vector (unsigned int vector) { }
-#define startup_level_ioapic   startup_level_ioapic_vector
-#define shutdown_level_ioapic  mask_IO_APIC_vector
-#define enable_level_ioapic    unmask_IO_APIC_vector
-#define disable_level_ioapic   mask_IO_APIC_vector
-#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_vector
-#define end_level_ioapic       end_level_ioapic_vector
-#define set_ioapic_affinity    set_ioapic_affinity_vector
-
-#define startup_edge_ioapic    startup_edge_ioapic_vector
-#define shutdown_edge_ioapic   disable_edge_ioapic_vector
-#define enable_edge_ioapic     unmask_IO_APIC_vector
-#define disable_edge_ioapic    disable_edge_ioapic_vector
-#define ack_edge_ioapic        ack_edge_ioapic_vector
-#define end_edge_ioapic        end_edge_ioapic_vector
-#else
-static inline int use_pci_vector(void) {return 0;}
-static inline void disable_edge_ioapic_irq(unsigned int irq) { }
-static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { }
-static inline void end_edge_ioapic_irq (unsigned int irq) { }
-#define startup_level_ioapic   startup_level_ioapic_irq
-#define shutdown_level_ioapic  mask_IO_APIC_irq
-#define enable_level_ioapic    unmask_IO_APIC_irq
-#define disable_level_ioapic   mask_IO_APIC_irq
-#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq
-#define end_level_ioapic       end_level_ioapic_irq
-#define set_ioapic_affinity    set_ioapic_affinity_irq
-
-#define startup_edge_ioapic    startup_edge_ioapic_irq
-#define shutdown_edge_ioapic   disable_edge_ioapic_irq
-#define enable_edge_ioapic     unmask_IO_APIC_irq
-#define disable_edge_ioapic    disable_edge_ioapic_irq
-#define ack_edge_ioapic        ack_edge_ioapic_irq
-#define end_edge_ioapic        end_edge_ioapic_irq
-#endif
-
-#define IO_APIC_BASE(idx) \
-               ((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \
-               + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))
-
-/*
- * The structure of the IO-APIC:
- */
-union IO_APIC_reg_00 {
-       u32     raw;
-       struct {
-               u32     __reserved_2    : 14,
-                       LTS             :  1,
-                       delivery_type   :  1,
-                       __reserved_1    :  8,
-                       ID              :  8;
-       } __attribute__ ((packed)) bits;
-};
-
-union IO_APIC_reg_01 {
-       u32     raw;
-       struct {
-               u32     version         :  8,
-                       __reserved_2    :  7,
-                       PRQ             :  1,
-                       entries         :  8,
-                       __reserved_1    :  8;
-       } __attribute__ ((packed)) bits;
-};
-
-union IO_APIC_reg_02 {
-       u32     raw;
-       struct {
-               u32     __reserved_2    : 24,
-                       arbitration     :  4,
-                       __reserved_1    :  4;
-       } __attribute__ ((packed)) bits;
-};
-
-union IO_APIC_reg_03 {
-       u32     raw;
-       struct {
-               u32     boot_DT         :  1,
-                       __reserved_1    : 31;
-       } __attribute__ ((packed)) bits;
-};
-
-/*
- * # of IO-APICs and # of IRQ routing registers
- */
-extern int nr_ioapics;
-extern int nr_ioapic_registers[MAX_IO_APICS];
-
-enum ioapic_irq_destination_types {
-       dest_Fixed = 0,
-       dest_LowestPrio = 1,
-       dest_SMI = 2,
-       dest__reserved_1 = 3,
-       dest_NMI = 4,
-       dest_INIT = 5,
-       dest__reserved_2 = 6,
-       dest_ExtINT = 7
-};
-
-struct IO_APIC_route_entry {
-       __u32   vector          :  8,
-               delivery_mode   :  3,   /* 000: FIXED
-                                        * 001: lowest prio
-                                        * 111: ExtINT
-                                        */
-               dest_mode       :  1,   /* 0: physical, 1: logical */
-               delivery_status :  1,
-               polarity        :  1,
-               irr             :  1,
-               trigger         :  1,   /* 0: edge, 1: level */
-               mask            :  1,   /* 0: enabled, 1: disabled */
-               __reserved_2    : 15;
-
-       union {         struct { __u32
-                                       __reserved_1    : 24,
-                                       physical_dest   :  4,
-                                       __reserved_2    :  4;
-                       } physical;
-
-                       struct { __u32
-                                       __reserved_1    : 24,
-                                       logical_dest    :  8;
-                       } logical;
-       } dest;
-
-} __attribute__ ((packed));
-
-/*
- * MP-BIOS irq configuration table structures:
- */
-
-/* I/O APIC entries */
-extern struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
-
-/* # of MP IRQ source entries */
-extern int mp_irq_entries;
-
-/* MP IRQ source entries */
-extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
-
-/* non-0 if default (table-less) MP configuration */
-extern int mpc_default_type;
-
-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
-{
-       physdev_op_t op;
-       int ret;
-
-       op.cmd = PHYSDEVOP_APIC_READ;
-       op.u.apic_op.apic = apic;
-       op.u.apic_op.offset = reg;
-       ret = HYPERVISOR_physdev_op(&op);
-       if (ret)
-               return ret;
-       return op.u.apic_op.value;
-}
-
-static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
-{
-       physdev_op_t op;
-
-       op.cmd = PHYSDEVOP_APIC_WRITE;
-       op.u.apic_op.apic = apic;
-       op.u.apic_op.offset = reg;
-       op.u.apic_op.value = value;
-       HYPERVISOR_physdev_op(&op);
-}
-
-/*
- * Re-write a value: to be used for read-modify-write
- * cycles where the read already set up the index register.
- *
- * Older SiS APIC requires we rewrite the index regiser
- */
-extern int sis_apic_bug;
-static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
-{
-       if (sis_apic_bug)
-               *IO_APIC_BASE(apic) = reg;
-       *(IO_APIC_BASE(apic)+4) = value;
-}
-
-/* 1 if "noapic" boot option passed */
-extern int skip_ioapic_setup;
-
-/*
- * If we use the IO-APIC for IRQ routing, disable automatic
- * assignment of PCI IRQ's.
- */
-#define io_apic_assign_pci_irqs (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs)
-
-#ifdef CONFIG_ACPI_BOOT
-extern int io_apic_get_unique_id (int ioapic, int apic_id);
-extern int io_apic_get_version (int ioapic);
-extern int io_apic_get_redir_entries (int ioapic);
-extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low);
-#endif /*CONFIG_ACPI_BOOT*/
-
-extern int (*ioapic_renumber_irq)(int ioapic, int irq);
-
-#else  /* !CONFIG_X86_IO_APIC */
-#define io_apic_assign_pci_irqs 0
-#endif
-
-extern int assign_irq_vector(int irq);
-
-#endif
index ba5dd9ccdc3f74cf422b41a155aa34943f3d5b0b..94fe34dc527211033a65ed70b98b2337c08f30d7 100644 (file)
@@ -16,14 +16,6 @@ int xc_physdev_pci_access_modify(int xc_handle,
                                  int func,
                                  int enable)
 {
-    dom0_op_t op;
-
-    op.cmd = DOM0_PCIDEV_ACCESS;
-    op.u.pcidev_access.domain = (domid_t)domid;
-    op.u.pcidev_access.bus    = bus;
-    op.u.pcidev_access.dev    = dev;
-    op.u.pcidev_access.func   = func;
-    op.u.pcidev_access.enable = enable;
-
-    return do_dom0_op(xc_handle, &op);
+    errno = ENOSYS;
+    return -1;
 }
index 056e9a711b084b12008f14cb3f860148e3f16f42..9f0d9d20ba18817222ca164deba7537463d36fe2 100644 (file)
@@ -621,8 +621,6 @@ int construct_dom0(struct domain *d,
        unsigned long pkern_entry;
        unsigned long pkern_end;
 
-       extern void physdev_init_dom0(struct domain *);
-
 //printf("construct_dom0: starting\n");
        /* Sanity! */
 #ifndef CLONE_DOMAIN0
@@ -755,12 +753,6 @@ int construct_dom0(struct domain *d,
 #endif
        console_endboot(strstr(cmdline, "tty0") != NULL);
 
-       /* DOM0 gets access to everything. */
-#ifdef CLONE_DOMAIN0
-if (d == dom0)
-#endif
-       physdev_init_dom0(d);
-
        set_bit(DF_CONSTRUCTED, &d->d_flags);
 
        new_thread(ed, pkern_entry, 0, 0);
index 241072ee85e2163447873a417e6f3485f33b8b16..8d94e3f53634e33c2a6c91a6945143ce99f04bf8 100644 (file)
@@ -149,33 +149,6 @@ void dump_pageframe_info(struct domain *d)
        printk("dump_pageframe_info not implemented\n");
 }
 
-///////////////////////////////
-// from common/physdev.c
-///////////////////////////////
-void
-physdev_init_dom0(struct domain *d)
-{
-}
-
-int
-physdev_pci_access_modify(domid_t id, int bus, int dev, int func, int enable)
-{
-       return -EINVAL;
-}
-
-void physdev_modify_ioport_access_range(struct domain *d, int enable,
-       int port, int num)
-{
-       printk("physdev_modify_ioport_access_range not implemented\n");
-       dummy();
-}
-
-void physdev_destroy_state(struct domain *d)
-{
-       printk("physdev_destroy_state not implemented\n");
-       dummy();
-}
-
 ///////////////////////////////
 // called from arch/ia64/head.S
 ///////////////////////////////
index 2c24a872eaf728bf2ca7a48b96110a6d3d118413..7d497ea40c7e1ce3c8f5a962750ea6955f563ddc 100644 (file)
@@ -69,9 +69,6 @@ unsigned char opt_pdb[10] = "none";
 unsigned int opt_tbuf_size = 10;
 /* opt_sched: scheduler - default to Borrowed Virtual Time */
 char opt_sched[10] = "bvt";
-/* opt_physdev_dom0_hide: list of PCI slots to hide from domain 0. */
-/* Format is '(%02x:%02x.%1x)(%02x:%02x.%1x)' and so on. */
-char opt_physdev_dom0_hide[200] = "";
 /* opt_leveltrigger, opt_edgetrigger: Force an IO-APIC-routed IRQ to be */
 /*                                    level- or edge-triggered.         */
 /* Example: 'leveltrigger=4,5,6,20 edgetrigger=21'. */
index ea14c5855f4cc4ac7862c2e500061fdc12c1b4b4..3d275206b45348ffd7df05985e201b28a8942adb 100644 (file)
@@ -37,6 +37,7 @@
 #include <asm/vmx.h>
 #include <asm/vmx_vmcs.h>
 #include <asm/msr.h>
+#include <asm/physdev.h>
 #include <xen/kernel.h>
 #include <public/io/ioreq.h>
 #include <xen/multicall.h>
@@ -968,6 +969,8 @@ void domain_relinquish_resources(struct domain *d)
 
     BUG_ON(d->cpuset != 0);
 
+    physdev_destroy_state(d);
+
     ptwr_destroy(d);
 
     /* Release device mappings of other domains */
index 3811183d9e90e29a6a1e27ba6f673b5bf87a9c35..f5c195a565025d5e4b8e1c3f6c02544b4dda9cf9 100644 (file)
@@ -615,9 +615,7 @@ static inline int IO_APIC_irq_trigger(int irq)
 
 int irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 };
 
-#ifdef CONFIG_VMX
 int vector_irq[256];
-#endif
 
 int assign_irq_vector(int irq)
 {
@@ -641,10 +639,10 @@ next:
                panic("ran out of interrupt sources!");
 
        IO_APIC_VECTOR(irq) = current_vector;
-#ifdef CONFIG_VMX
+
         vector_irq[current_vector] = irq;
-        printk("vector_irq[%x] = %d\n", current_vector, irq);
-#endif
+        DPRINTK("vector_irq[%x] = %d\n", current_vector, irq);
+
        return current_vector;
 }
 
@@ -1627,6 +1625,16 @@ static inline void check_timer(void)
        panic("IO-APIC + timer doesn't work! pester mingo@redhat.com");
 }
 
+#define NR_IOAPIC_BIOSIDS 256
+static u8 ioapic_biosid_to_apic_enum[NR_IOAPIC_BIOSIDS];
+static void store_ioapic_biosid_mapping(void)
+{
+    u8 apic;
+    memset(ioapic_biosid_to_apic_enum, ~0, NR_IOAPIC_BIOSIDS);
+    for ( apic = 0; apic < nr_ioapics; apic++ )
+        ioapic_biosid_to_apic_enum[mp_ioapics[apic].mpc_apicid] = apic;
+}
+
 /*
  *
  * IRQ's that are handled by the old PIC in all cases:
@@ -1646,6 +1654,8 @@ static inline void check_timer(void)
 
 void __init setup_IO_APIC(void)
 {
+       store_ioapic_biosid_mapping();
+
        enable_IO_APIC();
 
        io_apic_irqs = ~PIC_IRQS;
@@ -1949,3 +1959,67 @@ static int __init ioapic_trigger_setup(void)
 }
 
 __initcall(ioapic_trigger_setup);
+
+int ioapic_guest_read(int apicid, int address, u32 *pval)
+{
+    u32 val;
+    int apicenum;
+    struct IO_APIC_reg_00 reg_00;
+    unsigned long flags;
+
+    if ( (apicid >= NR_IOAPIC_BIOSIDS) ||
+         ((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) )
+            return -EINVAL;
+
+    spin_lock_irqsave(&ioapic_lock, flags);
+    val = io_apic_read(apicenum, address);
+    spin_unlock_irqrestore(&ioapic_lock, flags);
+
+    /* Rewrite APIC ID to what the BIOS originally specified. */
+    if ( address == 0 )
+    {
+        *(int *)&reg_00 = val;
+        reg_00.ID = apicid;
+        val = *(u32 *)&reg_00;
+    }
+
+    *pval = val;
+    return 0;
+}
+
+int ioapic_guest_write(int apicid, int address, u32 val)
+{
+    int apicenum, pin, irq;
+    struct IO_APIC_route_entry rte = { 0 };
+    unsigned long flags;
+
+    if ( (apicid >= NR_IOAPIC_BIOSIDS) ||
+         ((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) )
+            return -EINVAL;
+
+    /* Only write to the first half of a route entry. */
+    if ( (address < 0x10) || (address & 1) )
+        return 0;
+    
+    pin = (address - 0x10) >> 1;
+
+    rte.dest.logical.logical_dest = target_cpus();
+    *(int *)&rte = val;
+
+    /* Make sure we handle edge/level triggering correctly. */
+    if ( !rte.mask )
+    {
+        irq = vector_irq[rte.vector];
+        if ( !IO_APIC_IRQ(irq) )
+            return 0;
+        irq_desc[irq].handler = rte.trigger ? 
+            &ioapic_level_irq_type: &ioapic_edge_irq_type;
+    }
+    
+    spin_lock_irqsave(&ioapic_lock, flags);
+    io_apic_write(apicenum, 0x10 + 2 * pin, *(((int *)&rte) + 0));
+    io_apic_write(apicenum, 0x11 + 2 * pin, *(((int *)&rte) + 1));
+    spin_unlock_irqrestore(&ioapic_lock, flags);
+
+    return 0;
+}
diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c
new file mode 100644 (file)
index 0000000..9e47826
--- /dev/null
@@ -0,0 +1,145 @@
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/types.h>
+#include <xen/sched.h>
+#include <xen/irq.h>
+#include <xen/event.h>
+#include <asm/smpboot.h>
+#include <public/xen.h>
+#include <public/physdev.h>
+
+extern void (*interrupt[])(void);
+
+extern int ioapic_guest_read(int apicid, int address, u32 *pval);
+extern int ioapic_guest_write(int apicid, int address, u32 pval);
+
+void physdev_modify_ioport_access_range(
+    struct domain *d, int enable, int port, int num)
+{
+    int i;
+    for ( i = port; i < (port + num); i++ )
+        (enable ? clear_bit : set_bit)(i, d->arch.iobmp_mask);
+}
+
+void physdev_destroy_state(struct domain *d)
+{
+    xfree(d->arch.iobmp_mask);
+    d->arch.iobmp_mask = NULL;
+}
+
+/* Check if a domain controls a device with IO memory within frame @pfn.
+ * Returns: 1 if the domain should be allowed to map @pfn, 0 otherwise.  */
+int domain_iomem_in_pfn(struct domain *p, unsigned long pfn)
+{
+    return 0;
+}
+
+/*
+ * Demuxing hypercall.
+ */
+long do_physdev_op(physdev_op_t *uop)
+{
+    physdev_op_t op;
+    long         ret;
+    int          irq;
+
+    if ( unlikely(copy_from_user(&op, uop, sizeof(op)) != 0) )
+        return -EFAULT;
+
+    switch ( op.cmd )
+    {
+    case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
+        ret = pirq_guest_unmask(current->domain);
+        break;
+
+    case PHYSDEVOP_IRQ_STATUS_QUERY:
+        irq = op.u.irq_status_query.irq;
+        ret = -EINVAL;
+        if ( (irq < 0) || (irq >= NR_IRQS) )
+            break;
+        op.u.irq_status_query.flags = 0;
+        /* Edge-triggered interrupts don't need an explicit unmask downcall. */
+        if ( strstr(irq_desc[irq].handler->typename, "edge") == NULL )
+            op.u.irq_status_query.flags |= PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY;
+        ret = 0;
+        break;
+
+    case PHYSDEVOP_APIC_READ:
+        ret = -EPERM;
+        if ( !IS_PRIV(current->domain) )
+            break;
+        ret = ioapic_guest_read(
+            op.u.apic_op.apic, op.u.apic_op.offset, &op.u.apic_op.value);
+        break;
+
+    case PHYSDEVOP_APIC_WRITE:
+        ret = -EPERM;
+        if ( !IS_PRIV(current->domain) )
+            break;
+        ret = ioapic_guest_write(
+            op.u.apic_op.apic, op.u.apic_op.offset, op.u.apic_op.value);
+        break;
+
+    case PHYSDEVOP_ASSIGN_VECTOR:
+        if ( !IS_PRIV(current->domain) )
+            return -EPERM;
+
+        if ( (irq = op.u.irq_op.irq) >= NR_IRQS )
+            return -EINVAL;
+        
+        op.u.irq_op.vector = assign_irq_vector(irq);
+        set_intr_gate(op.u.irq_op.vector, interrupt[irq]);
+        ret = 0;
+        break;
+
+    case PHYSDEVOP_SET_IOPL:
+        ret = -EINVAL;
+        if ( op.u.set_iopl.iopl > 3 )
+            break;
+        ret = 0;
+        current->arch.iopl = op.u.set_iopl.iopl;
+        break;
+
+    case PHYSDEVOP_SET_IOBITMAP:
+        ret = -EINVAL;
+        if ( !access_ok(op.u.set_iobitmap.bitmap, IOBMP_BYTES) ||
+             (op.u.set_iobitmap.nr_ports > 65536) )
+            break;
+        ret = 0;
+        current->arch.iobmp       = (u8 *)op.u.set_iobitmap.bitmap;
+        current->arch.iobmp_limit = op.u.set_iobitmap.nr_ports;
+        break;
+    default:
+        ret = -EINVAL;
+        break;
+    }
+
+    if ( copy_to_user(uop, &op, sizeof(op)) )
+        ret = -EFAULT;
+
+    return ret;
+}
+
+/* Domain 0 has read access to all devices. */
+void physdev_init_dom0(struct domain *d)
+{
+    /* Access to all I/O ports. */
+    d->arch.iobmp_mask = xmalloc_array(u8, IOBMP_BYTES);
+    BUG_ON(d->arch.iobmp_mask == NULL);
+    memset(d->arch.iobmp_mask, 0, IOBMP_BYTES);
+
+    set_bit(DF_PHYSDEV, &d->d_flags);
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
index e832864584eaeb1d99fe75880c8d55f8aad78392..ee312fde921cca7813ee2c419c70d44830baa571 100644 (file)
@@ -4,7 +4,6 @@ include $(BASEDIR)/Rules.mk
 ifeq ($(TARGET_ARCH),ia64) 
 OBJS := $(subst dom_mem_ops.o,,$(OBJS))
 OBJS := $(subst grant_table.o,,$(OBJS))
-OBJS := $(subst physdev.o,,$(OBJS))
 endif
 
 ifneq ($(perfc),y)
index 5634fc39363ecc7a8d7154c4d66cbbc9f02248e4..750eb14813789c8a80d5e873610b3961f6c2c64b 100644 (file)
@@ -16,7 +16,6 @@
 #include <asm/domain_page.h>
 #include <xen/trace.h>
 #include <xen/console.h>
-#include <xen/physdev.h>
 #include <public/sched_ctl.h>
 
 extern long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op);
@@ -385,16 +384,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     }
     break;
 
-    case DOM0_PCIDEV_ACCESS:
-    {
-        ret = physdev_pci_access_modify(op->u.pcidev_access.domain, 
-                                        op->u.pcidev_access.bus,
-                                        op->u.pcidev_access.dev,
-                                        op->u.pcidev_access.func,
-                                        op->u.pcidev_access.enable);
-    }
-    break;
-
     case DOM0_SCHED_ID:
     {
         op->u.sched_id.sched_id = sched_id();
index ea2ea364a5e805469f673cf33343c9dad6228226..253a6b102be1cbed29f849ee8ba9f502603ee6b7 100644 (file)
@@ -50,10 +50,6 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
     INIT_LIST_HEAD(&d->page_list);
     INIT_LIST_HEAD(&d->xenpage_list);
 
-    /* Per-domain PCI-device list. */
-    spin_lock_init(&d->pcidev_lock);
-    INIT_LIST_HEAD(&d->pcidev_list);
-    
     if ( (d->id != IDLE_DOMAIN_ID) &&
          ((init_event_channels(d) != 0) || (grant_table_create(d) != 0)) )
     {
@@ -106,12 +102,6 @@ struct domain *find_domain_by_id(domid_t dom)
 }
 
 
-#ifndef CONFIG_IA64
-extern void physdev_destroy_state(struct domain *d);
-#else
-#define physdev_destroy_state(_d) ((void)0)
-#endif
-
 void domain_kill(struct domain *d)
 {
     struct exec_domain *ed;
@@ -122,7 +112,6 @@ void domain_kill(struct domain *d)
         for_each_exec_domain(d, ed)
             sched_rem_domain(ed);
         domain_relinquish_resources(d);
-        physdev_destroy_state(d);
         put_domain(d);
     }
 }
diff --git a/xen/common/physdev.c b/xen/common/physdev.c
deleted file mode 100644 (file)
index d533d93..0000000
+++ /dev/null
@@ -1,832 +0,0 @@
-/****************************************************************************
- * (c) 2004 - Rolf Neugebauer - Intel Research Cambridge
- * (c) 2004 - Keir Fraser - University of Cambridge
- ****************************************************************************
- * 
- * Description: allows a domain to access devices on the PCI bus
- *
- * A guest OS may be given access to particular devices on the PCI bus.
- * For each domain a list of PCI devices is maintained, describing the
- * access mode for the domain. 
- *
- * Guests can figure out the virtualised PCI space through normal PCI config
- * register access. Some of the accesses, in particular write accesses, are
- * faked. For example the sequence for detecting the IO regions, which requires
- * writes to determine the size of the region, is faked out by a very simple
- * state machine, preventing direct writes to the PCI config registers by a
- * guest.
- */
-
-#include <xen/config.h>
-#include <xen/init.h>
-#include <xen/lib.h>
-#include <xen/types.h>
-#include <xen/sched.h>
-#include <xen/pci.h>
-#include <xen/irq.h>
-#include <xen/event.h>
-#include <asm/pci.h>
-#include <public/xen.h>
-#include <public/physdev.h>
-
-/* Called by PHYSDEV_PCI_INITIALISE_DEVICE to finalise IRQ routing. */
-extern void pcibios_enable_irq(struct pci_dev *dev);
-
-#if 0
-#define VERBOSE_INFO(_f, _a...) printk( _f , ## _a )
-#else
-#define VERBOSE_INFO(_f, _a...) ((void)0)
-#endif
-
-#ifdef VERBOSE
-#define INFO(_f, _a...) printk( _f, ## _a )
-#else
-#define INFO(_f, _a...) ((void)0)
-#endif
-
-#define SLOPPY_CHECKING
-
-#define ACC_READ  1
-#define ACC_WRITE 2
-
-/* Upper bounds for PCI-device addressing. */
-#define PCI_BUSMAX  255
-#define PCI_DEVMAX   31
-#define PCI_FUNCMAX   7
-#define PCI_REGMAX  255
-
-/* Bit offsets into state. */
-#define ST_BASE_ADDRESS  0   /* bits 0-5: are for base address access */
-#define ST_ROM_ADDRESS   6   /* bit 6: is for rom address access */    
-
-typedef struct _phys_dev_st {
-    int flags;                       /* flags for access etc */
-    struct pci_dev *dev;             /* the device */
-    struct list_head node;           /* link to the list */
-    struct domain *owner;       /* 'owner of this device' */
-    int state;                       /* state for various checks */
-} phys_dev_t;
-
-
-/* Find a device on a per-domain device list. */
-static phys_dev_t *find_pdev(struct domain *d, struct pci_dev *dev)
-{
-    phys_dev_t *t;
-    list_for_each_entry ( t, &d->pcidev_list, node )
-        if ( dev == t->dev )
-            return t;
-    return NULL;
-}
-
-static int setup_ioport_memory_access(struct domain *d, struct pci_dev *pdev)
-{
-    struct resource *r;
-    int i, j;
-
-    if ( d->arch.iobmp_mask == NULL )
-    {
-        if ( (d->arch.iobmp_mask = xmalloc_array(u8, IOBMP_BYTES)) == NULL )
-            return -ENOMEM;
-        memset(d->arch.iobmp_mask, 0xFF, IOBMP_BYTES);
-    }
-
-    for ( i = 0; i < DEVICE_COUNT_RESOURCE; i++ )
-    {
-        r = &pdev->resource[i];         
-        if ( r->flags & IORESOURCE_IO )
-        {
-            INFO("Giving domain %u IO resources (%lx - %lx) "
-                 "for device %s\n", d->id, r->start, r->end, pdev->slot_name);
-            for ( j = r->start; j < r->end + 1; j++ )
-                clear_bit(j, d->arch.iobmp_mask);
-        }
-    }
-
-    return 0;
-}
-
-void physdev_modify_ioport_access_range(
-    struct domain *d, int enable, int port, int num)
-{
-    int i;
-    for ( i = port; i < (port + num); i++ )
-        (enable ? clear_bit : set_bit)(i, d->arch.iobmp_mask);
-}
-
-/* Add a device to a per-domain device-access list. */
-static int add_dev_to_task(struct domain *d, struct pci_dev *dev, int acc)
-{
-    phys_dev_t *physdev;
-    int         rc;
-    
-    if ( (physdev = xmalloc(phys_dev_t)) == NULL )
-    {
-        INFO("Error allocating pdev structure.\n");
-        return -ENOMEM;
-    }
-    
-    if ( (rc = setup_ioport_memory_access(d, dev)) < 0 )
-    {
-        xfree(physdev);
-        return rc;
-    }
-
-    physdev->dev = dev;
-    physdev->flags = acc;
-    physdev->state = 0;
-    list_add(&physdev->node, &d->pcidev_list);
-
-    if ( acc == ACC_WRITE )
-        physdev->owner = d;
-
-    return 0;
-}
-
-void physdev_destroy_state(struct domain *d)
-{
-    struct list_head *ent;
-
-    xfree(d->arch.iobmp_mask);
-    d->arch.iobmp_mask = NULL;
-
-    while ( (ent = d->pcidev_list.next) != &d->pcidev_list )
-    {
-        list_del(ent);
-        xfree(list_entry(ent, phys_dev_t, node));
-    }
-}
-
-/*
- * physdev_pci_access_modify:
- * Allow/disallow access to a specific PCI device.  Guests should not be
- * allowed to see bridge devices as it needlessly complicates things (one
- * possible exception to this is the AGP bridge).
- */
-int physdev_pci_access_modify(domid_t dom, int bus, int dev, int func, 
-                              int enable)
-{
-    struct domain *p;
-    struct pci_dev *pdev;
-    phys_dev_t *physdev;
-    int rc = 0;
-    int oldacc = -1;
-
-    BUG_ON(!IS_PRIV(current->domain));
-
-    if ( (bus > PCI_BUSMAX) || (dev > PCI_DEVMAX) || (func > PCI_FUNCMAX) )
-        return -EINVAL;
-
-    if ( !enable )
-    {
-        INFO("Disallowing access is not yet supported.\n");
-        return -EINVAL;
-    }
-
-    INFO("physdev_pci_access_modify: %02x:%02x:%02x\n", bus, dev, func);
-
-    if ( (p = find_domain_by_id(dom)) == NULL ) 
-        return -ESRCH;
-
-    /* Make the domain privileged. */
-    set_bit(DF_PHYSDEV, &p->d_flags);
-    /* FIXME: MAW for now make the domain REALLY privileged so that it
-     * can run a backend driver (hw access should work OK otherwise) */
-    set_bit(DF_PRIVILEGED, &p->d_flags);
-
-    /* Grant write access to the specified device. */
-    if ( (pdev = pci_find_slot(bus, PCI_DEVFN(dev, func))) == NULL )
-    {
-        INFO("  dev does not exist\n");
-        rc = -ENODEV;
-        goto out;
-    }
-    
-    INFO("  add RW %02x:%02x:%02x\n", pdev->bus->number,
-         PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
-
-    if ( (physdev = find_pdev(p, pdev)) != NULL )
-    {
-        oldacc = physdev->flags;
-        physdev->flags = ACC_WRITE;
-    }
-    else
-    {
-        rc = add_dev_to_task(p, pdev, ACC_WRITE);
-    }
-
- out:
-    put_domain(p);
-    return rc;
-}
-
-/* Check if a domain controls a device with IO memory within frame @pfn.
- * Returns: 1 if the domain should be allowed to map @pfn, 0 otherwise.  */
-int domain_iomem_in_pfn(struct domain *p, unsigned long pfn)
-{
-    int ret = 0;
-    phys_dev_t *phys_dev;
-
-    VERBOSE_INFO("Checking if physdev-capable domain %u needs access to "
-                 "pfn %p\n", p->id, pfn);
-    
-    spin_lock(&p->pcidev_lock);
-
-    list_for_each_entry ( phys_dev, &p->pcidev_list, node )
-    {
-        int i;
-        struct pci_dev *pci_dev = phys_dev->dev;
-
-        for ( i = 0; (i < DEVICE_COUNT_RESOURCE) && (ret == 0); i++ )
-        {
-            struct resource *r = &pci_dev->resource[i];
-            
-            if ( r->flags & IORESOURCE_MEM )
-                if ( (r->start >> PAGE_SHIFT) == pfn
-                     || (r->end >> PAGE_SHIFT) == pfn
-                     || ((r->start >> PAGE_SHIFT < pfn)
-                         && (r->end >> PAGE_SHIFT > pfn)) )
-                    ret = 1;
-        }
-
-        if ( ret != 0 ) break;
-    }
-    
-    spin_unlock(&p->pcidev_lock);
-
-    VERBOSE_INFO("Domain %u %s mapping of pfn %p\n",
-                 p->id, ret ? "allowed" : "disallowed", pfn);
-
-    return ret;
-}
-
-/* check if a domain has general access to a device */
-static inline int check_dev_acc(
-    struct domain *d, int bus, int dev, int func, phys_dev_t **pdev)
-{
-    struct pci_dev *target_dev;
-    phys_dev_t     *target_pdev;
-    unsigned int    target_devfn;
-
-    *pdev = NULL;
-
-     if ( !IS_CAPABLE_PHYSDEV(d) )
-         return -EPERM;
-
-    if ( (bus > PCI_BUSMAX) || (dev > PCI_DEVMAX) || (func > PCI_FUNCMAX) )
-        return -EINVAL;
-
-    VERBOSE_INFO("b=%x d=%x f=%x ", bus, dev, func);
-
-    /* check target device */
-    target_devfn = PCI_DEVFN(dev, func);
-    target_dev   = pci_find_slot(bus, target_devfn);
-    if ( !target_dev )
-    {
-        VERBOSE_INFO("target does not exist\n");
-        return -ENODEV;
-    }
-
-    /* check access */
-    target_pdev = find_pdev(d, target_dev);
-    if ( !target_pdev )
-    {
-        VERBOSE_INFO("dom has no access to target\n");
-        return -EPERM;
-    }
-
-    *pdev = target_pdev;
-    return 0;
-}
-
-#ifndef SLOPPY_CHECKING
-/*
- * Base address registers contain the base address for IO regions.
- * The length can be determined by writing all 1s to the register and
- * reading the value again. The device will zero the lower unused bits.
- * 
- * to work out the length of the io region a device probe typically does:
- * 1) a = read_base_addr_reg()
- * 2) write_base_addr_reg(0xffffffff)
- * 3) b = read_base_addr_reg()  [device zeros lower bits]
- * 4) write_base_addr_reg(a)    [restore original value]
- * this function fakes out step 2-4. *no* writes are made to the device.
- * 
- * phys_dev_t contains a bit field (a bit for each base address register).
- * if the bit for a register is set the guest had writen all 1s to the 
- * register and subsequent read request need to fake out the b.
- * if the guest restores the original value (step 4 above) the bit is
- * cleared again. If the guest attempts to "restores" a wrong value an
- * error is flagged.
- */
-static int do_base_address_access(phys_dev_t *pdev, int acc, int idx, 
-                                  int len, u32 *val)
-{
-    int st_bit, reg = PCI_BASE_ADDRESS_0 + (idx*4), ret = -EINVAL;
-    struct pci_dev *dev = pdev->dev;
-    u32 orig_val, sz;
-    struct resource *res;
-
-    if ( len != sizeof(u32) )
-    {
-        /* This isn't illegal, but there doesn't seem to be a very good reason
-         * to do it for normal devices (bridges are another matter).  Since it
-         * would complicate the code below, we don't support this for now. */
-
-        /* We could set *val to some value but the guest may well be in trouble
-         * anyway if this write fails.  Hopefully the printk will give us a
-         * clue what went wrong. */
-        INFO("Guest %u attempting sub-dword %s to BASE_ADDRESS %d\n",
-             pdev->owner->id, (acc == ACC_READ) ? "read" : "write", idx);
-        
-        return -EPERM;
-    }
-
-    st_bit = idx + ST_BASE_ADDRESS;
-    res    = &(pdev->dev->resource[idx]);
-
-    if ( acc == ACC_WRITE )
-    {
-        if ( (*val == 0xffffffff) || 
-             ((res->flags & IORESOURCE_IO) && (*val == 0xffff)) )
-        {
-            /* Set bit and return. */
-            set_bit(st_bit, &pdev->state);
-            ret = 0;
-        }
-        else
-        {
-            /* Assume guest wants to set the base address. */
-            clear_bit(st_bit, &pdev->state);
-
-            /* check if guest tries to restore orig value */
-            ret = pci_read_config_dword(dev, reg, &orig_val);
-            if ( (ret == 0) && (*val != orig_val) ) 
-            {
-                INFO("Guest attempting update to BASE_ADDRESS %d\n", idx);
-                ret = -EPERM;
-            }
-        }
-        VERBOSE_INFO("fixed pci write: %02x:%02x:%02x reg=0x%02x len=0x%02x"
-                     " val=0x%08x %x\n", 
-                     dev->bus->number, PCI_SLOT(dev->devfn), 
-                     PCI_FUNC(dev->devfn), reg, len, *val, pdev->state);
-    }
-    else if ( acc == ACC_READ )
-    {
-        ret = pci_read_config_dword(dev, reg, val);
-        if ( (ret == 0) && test_bit(st_bit, &pdev->state) )
-        {
-            /* Cook the value. */
-            sz  = res->end - res->start;
-            if ( res->flags & IORESOURCE_MEM )
-            {
-                /* this is written out explicitly for clarity */
-                *val = 0xffffffff;
-                /* bit    0 = 0 */
-                /* bit  21  = memory type */
-                /* bit 3    = prefetchable */
-                /* bit 4-31 width */
-                sz   = sz >> 4; /* size in blocks of 16 byte */
-                sz   = ~sz;     /* invert */
-                *val = *val & (sz << 4); /* and in the size */
-                /* use read values for low 4 bits */
-                *val = *val | (orig_val & 0xf);
-            }
-            else if ( res->flags & IORESOURCE_IO )
-            {
-                *val = 0x0000ffff;
-                /* bit 10 = 01 */
-                /* bit 2-31 width */
-                sz   = sz >> 2; /* size in dwords */
-                sz   = ~sz & 0x0000ffff;
-                *val = *val & (sz << 2);
-                *val = *val | 0x1;
-            }
-        }
-        VERBOSE_INFO("fixed pci read: %02x:%02x:%02x reg=0x%02x len=0x%02x"
-                     " val=0x%08x %x\n", 
-                     dev->bus->number, PCI_SLOT(dev->devfn), 
-                     PCI_FUNC(dev->devfn), reg, len, *val, pdev->state);
-    }
-
-    return ret;
-}
-
-
-static int do_rom_address_access(phys_dev_t *pdev, int acc, int len, u32 *val)
-{
-    int st_bit, ret = -EINVAL;
-    struct pci_dev *dev = pdev->dev;
-    u32 orig_val, sz;
-    struct resource *res;
-
-    if ( len != sizeof(u32) )
-    {
-        INFO("Guest attempting sub-dword %s to ROM_ADDRESS\n", 
-             (acc == ACC_READ) ? "read" : "write");
-        return -EPERM;
-    }
-
-    st_bit = ST_ROM_ADDRESS;
-    res = &(pdev->dev->resource[PCI_ROM_RESOURCE]);
-
-    if ( acc == ACC_WRITE )
-    {
-        if ( (*val == 0xffffffff) || (*val == 0xfffffffe) )
-        {
-            /* NB. 0xffffffff would be unusual, but we trap it anyway. */
-            set_bit(st_bit, &pdev->state);
-            ret = 0;
-        }
-        else
-        {
-            /* Assume guest wants simply to set the base address. */
-            clear_bit(st_bit, &pdev->state);
-            
-            /* Check if guest tries to restore the original value. */
-            ret = pci_read_config_dword(dev, PCI_ROM_ADDRESS, &orig_val);
-            if ( (ret == 0) && (*val != orig_val) ) 
-            {
-                if ( (*val != 0x00000000) )
-                {
-                    INFO("caution: guest tried to change rom address.\n");
-                    ret = -EPERM;
-                }
-                else
-                {
-                    INFO("guest disabled rom access for %02x:%02x:%02x\n",
-                         dev->bus->number, PCI_SLOT(dev->devfn), 
-                         PCI_FUNC(dev->devfn));
-                }
-            }
-        }
-        VERBOSE_INFO("fixed pci write: %02x:%02x:%02x reg=0x%02x len=0x%02x"
-                     " val=0x%08x %x\n", 
-                     dev->bus->number, PCI_SLOT(dev->devfn), 
-                     PCI_FUNC(dev->devfn), PCI_ROM_ADDRESS, len, *val, pdev->state);
-    }
-    else if ( acc == ACC_READ )
-    {
-        ret = pci_read_config_dword(dev, PCI_ROM_ADDRESS, val);
-        if ( (ret == 0) && test_bit(st_bit, &pdev->state) )
-        {
-            /* Cook the value. */
-            sz  = res->end - res->start;
-            *val = 0xffffffff;
-            /* leave bit 0 untouched */
-            /* bit 1-10 reserved, harwired to 0 */
-            sz = sz >> 11; /* size is in 2KB blocks */
-            sz = ~sz;
-            *val = *val & (sz << 11);
-            *val = *val | (orig_val & 0x1);
-        }
-        VERBOSE_INFO("fixed pci read: %02x:%02x:%02x reg=0x%02x len=0x%02x"
-                     " val=0x%08x %x\n", 
-                     dev->bus->number, PCI_SLOT(dev->devfn), 
-                     PCI_FUNC(dev->devfn), PCI_ROM_ADDRESS, len, *val, pdev->state);
-    }
-
-    return ret;
-
-}
-#endif /* SLOPPY_CHECKING */
-
-#ifdef CONFIG_PCI
-/*
- * Handle a PCI config space read access if the domain has access privileges.
- */
-static long pci_cfgreg_read(int bus, int dev, int func, int reg,
-                            int len, u32 *val)
-{
-    int ret;
-    phys_dev_t *pdev;
-
-    if ( (ret = check_dev_acc(current->domain, bus, dev, func, &pdev)) != 0 )
-    {
-        /* PCI spec states that reads from non-existent devices should return
-         * all 1s.  In this case the domain has no read access, which should
-         * also look like the device is non-existent. */
-        *val = 0xFFFFFFFF;
-        return ret;
-    }
-
-    /* Fake out read requests for some registers. */
-    switch ( reg )
-    {
-#ifndef SLOPPY_CHECKING
-    case PCI_BASE_ADDRESS_0:
-        ret = do_base_address_access(pdev, ACC_READ, 0, len, val);
-        break;
-
-    case PCI_BASE_ADDRESS_1:
-        ret = do_base_address_access(pdev, ACC_READ, 1, len, val);
-        break;
-
-    case PCI_BASE_ADDRESS_2:
-        ret = do_base_address_access(pdev, ACC_READ, 2, len, val);
-        break;
-
-    case PCI_BASE_ADDRESS_3:
-        ret = do_base_address_access(pdev, ACC_READ, 3, len, val);
-        break;
-
-    case PCI_BASE_ADDRESS_4:
-        ret = do_base_address_access(pdev, ACC_READ, 4, len, val);
-        break;
-
-    case PCI_BASE_ADDRESS_5:
-        ret = do_base_address_access(pdev, ACC_READ, 5, len, val);
-        break;
-
-    case PCI_ROM_ADDRESS:
-        ret = do_rom_address_access(pdev, ACC_READ, len, val);
-        break;        
-#endif
-
-    case PCI_INTERRUPT_LINE:
-        *val = pdev->dev->irq;
-        ret = 0;
-        break;
-
-    default:
-        ret = pci_config_read(0, bus, dev, func, reg, len, val);        
-        VERBOSE_INFO("pci read : %02x:%02x:%02x reg=0x%02x len=0x%02x "
-                     "val=0x%08x\n", bus, dev, func, reg, len, *val);
-        break;
-    }
-
-    return ret;
-}
-
-
-/*
- * Handle a PCI config space write access if the domain has access privileges.
- */
-static long pci_cfgreg_write(int bus, int dev, int func, int reg,
-                             int len, u32 val)
-{
-    int ret;
-    phys_dev_t *pdev;
-
-    if ( (ret = check_dev_acc(current->domain, bus, dev, func, &pdev)) != 0 )
-        return ret;
-
-    /* special treatment for some registers */
-    switch (reg)
-    {
-#ifndef SLOPPY_CHECKING
-    case PCI_BASE_ADDRESS_0:
-        ret = do_base_address_access(pdev, ACC_WRITE, 0, len, &val);
-        break;
-
-    case PCI_BASE_ADDRESS_1:
-        ret = do_base_address_access(pdev, ACC_WRITE, 1, len, &val);
-        break;
-
-    case PCI_BASE_ADDRESS_2:
-        ret = do_base_address_access(pdev, ACC_WRITE, 2, len, &val);
-        break;
-
-    case PCI_BASE_ADDRESS_3:
-        ret = do_base_address_access(pdev, ACC_WRITE, 3, len, &val);
-        break;
-
-    case PCI_BASE_ADDRESS_4:
-        ret = do_base_address_access(pdev, ACC_WRITE, 4, len, &val);
-        break;
-
-    case PCI_BASE_ADDRESS_5:
-        ret = do_base_address_access(pdev, ACC_WRITE, 5, len, &val);
-        break;
-
-    case PCI_ROM_ADDRESS:
-        ret = do_rom_address_access(pdev, ACC_WRITE, len, &val);
-        break;        
-#endif
-
-    default:
-        if ( pdev->flags != ACC_WRITE ) 
-        {
-            INFO("pci write not allowed %02x:%02x:%02x: "
-                 "reg=0x%02x len=0x%02x val=0x%08x\n",
-                 bus, dev, func, reg, len, val);
-            ret = -EPERM;
-        }
-        else
-        {
-            ret = pci_config_write(0, bus, dev, func, reg, len, val);
-            VERBOSE_INFO("pci write: %02x:%02x:%02x reg=0x%02x len=0x%02x "
-                         "val=0x%08x\n", bus, dev, func, reg, len, val);
-        }
-        break;
-    }
-
-    return ret;
-}
-
-
-static long pci_probe_root_buses(u32 *busmask)
-{
-    phys_dev_t *pdev;
-
-    memset(busmask, 0, 256/8);
-
-    list_for_each_entry ( pdev, &current->domain->pcidev_list, node )
-        set_bit(pdev->dev->bus->number, busmask);
-
-    return 0;
-}
-#endif
-
-/*
- * Demuxing hypercall.
- */
-long do_physdev_op(physdev_op_t *uop)
-{
-    physdev_op_t op;
-    long         ret;
-    u32          apic, irq;
-    u32          address, val;
-
-    if ( unlikely(copy_from_user(&op, uop, sizeof(op)) != 0) )
-        return -EFAULT;
-
-    switch ( op.cmd )
-    {
-#ifdef CONFIG_PCI
-    case PHYSDEVOP_PCI_CFGREG_READ:
-        ret = pci_cfgreg_read(op.u.pci_cfgreg_read.bus,
-                              op.u.pci_cfgreg_read.dev, 
-                              op.u.pci_cfgreg_read.func,
-                              op.u.pci_cfgreg_read.reg, 
-                              op.u.pci_cfgreg_read.len,
-                              &op.u.pci_cfgreg_read.value);
-        break;
-
-    case PHYSDEVOP_PCI_CFGREG_WRITE:
-        ret = pci_cfgreg_write(op.u.pci_cfgreg_write.bus,
-                               op.u.pci_cfgreg_write.dev, 
-                               op.u.pci_cfgreg_write.func,
-                               op.u.pci_cfgreg_write.reg, 
-                               op.u.pci_cfgreg_write.len,
-                               op.u.pci_cfgreg_write.value);
-        break;
-
-    case PHYSDEVOP_PCI_INITIALISE_DEVICE:
-        if ( (ret = check_dev_acc(current->domain, 
-                                  op.u.pci_initialise_device.bus, 
-                                  op.u.pci_initialise_device.dev, 
-                                  op.u.pci_initialise_device.func, 
-                                  &pdev)) == 0 )
-            pcibios_enable_irq(pdev->dev);
-        break;
-
-    case PHYSDEVOP_PCI_PROBE_ROOT_BUSES:
-        ret = pci_probe_root_buses(op.u.pci_probe_root_buses.busmask);
-        break;
-#endif
-    case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
-        ret = pirq_guest_unmask(current->domain);
-        break;
-
-    case PHYSDEVOP_IRQ_STATUS_QUERY:
-        irq = op.u.irq_status_query.irq;
-        ret = -EINVAL;
-        if ( (irq < 0) || (irq >= NR_IRQS) )
-            break;
-        op.u.irq_status_query.flags = 0;
-        /* Edge-triggered interrupts don't need an explicit unmask downcall. */
-        if ( strstr(irq_desc[irq].handler->typename, "edge") == NULL )
-            op.u.irq_status_query.flags |= PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY;
-        ret = 0;
-        break;
-#ifdef __ARCH_HAS_IOAPIC
-    case PHYSDEVOP_APIC_READ:
-        if ( !IS_PRIV(current->domain) )
-                return -EPERM;
-
-        apic = op.u.apic_op.apic;
-        address = op.u.apic_op.offset;
-        ret = -EINVAL;
-        if (apic >= nr_ioapics)
-            break;
-        val = io_apic_read(apic, address);
-        DPRINTK("ioapic read: %x = %x\n", address, val);
-        op.u.apic_op.value = val;
-        ret = 0;
-        break;
-    case PHYSDEVOP_APIC_WRITE:
-        if ( !IS_PRIV(current->domain) )
-                return -EPERM;
-
-        apic = op.u.apic_op.apic;
-        address = op.u.apic_op.offset;
-        val = op.u.apic_op.value;
-        ret = -EINVAL;
-        if (apic >= nr_ioapics)
-            break;
-
-        DPRINTK("ioapic write: %x = %x\n", address, val);
-        io_apic_write(apic, address, val);
-        ret = 0;
-        break;
-    case PHYSDEVOP_ASSIGN_VECTOR:
-        if ( !IS_PRIV(current->domain) )
-                return -EPERM;
-        
-        irq = op.u.irq_op.irq;
-        op.u.irq_op.vector = assign_irq_vector(irq);
-        ret = 0;
-        break;
-#endif
-    case PHYSDEVOP_SET_IOPL:
-        ret = -EINVAL;
-        if ( op.u.set_iopl.iopl > 3 )
-            break;
-        ret = 0;
-        current->arch.iopl = op.u.set_iopl.iopl;
-        break;
-
-    case PHYSDEVOP_SET_IOBITMAP:
-        ret = -EINVAL;
-        if ( !access_ok(op.u.set_iobitmap.bitmap, IOBMP_BYTES) ||
-             (op.u.set_iobitmap.nr_ports > 65536) )
-            break;
-        ret = 0;
-        current->arch.iobmp       = (u8 *)op.u.set_iobitmap.bitmap;
-        current->arch.iobmp_limit = op.u.set_iobitmap.nr_ports;
-        break;
-    default:
-        ret = -EINVAL;
-        break;
-    }
-
-    if (copy_to_user(uop, &op, sizeof(op)))
-        ret = -EFAULT;
-
-    return ret;
-}
-
-/* opt_physdev_dom0_hide: list of PCI slots to hide from domain 0. */
-/* Format is '(%02x:%02x.%1x)(%02x:%02x.%1x)' and so on. */
-static char opt_physdev_dom0_hide[200] = "";
-string_param("physdev_dom0_hide", opt_physdev_dom0_hide);
-
-/* Test if boot params specify this device should NOT be visible to DOM0
- * (e.g. so that another domain can control it instead) */
-static int pcidev_dom0_hidden(struct pci_dev *dev)
-{
-    char cmp[10] = "(.......)";
-    
-    strncpy(&cmp[1], dev->slot_name, 7);
-
-    if ( strstr(opt_physdev_dom0_hide, dev->slot_name) == NULL )
-        return 0;
-    
-    return 1;
-}
-
-
-/* Domain 0 has read access to all devices. */
-void physdev_init_dom0(struct domain *d)
-{
-    struct pci_dev *dev;
-    phys_dev_t *pdev;
-
-    /* Access to all I/O ports. */
-    d->arch.iobmp_mask = xmalloc_array(u8, IOBMP_BYTES);
-    BUG_ON(d->arch.iobmp_mask == NULL);
-    memset(d->arch.iobmp_mask, 0, IOBMP_BYTES);
-
-    /* Access to all PCI devices. */
-    pci_for_each_dev(dev)
-    {
-        if ( pcidev_dom0_hidden(dev) )
-        {            
-            printk("Hiding PCI device %s from DOM0\n", dev->slot_name);
-            continue;
-        }
-
-        pdev = xmalloc(phys_dev_t);
-        BUG_ON(pdev == NULL);
-
-        pdev->dev = dev;
-        pdev->flags = ACC_WRITE;
-        pdev->state = 0;
-        pdev->owner = d;
-        list_add(&pdev->node, &d->pcidev_list);
-    }
-
-    set_bit(DF_PHYSDEV, &d->d_flags);
-}
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
index ba58bc8a161b697d55373d3e2b60af88079bb397..ebfd44cea8cbcff5a724cc86858a81d4c015fca9 100644 (file)
 #include <xen/reboot.h>
 #include <xen/sched.h>
 #include <xen/serial.h>
-#include <xen/physdev.h>
 #include <asm/io.h>
 
+#ifdef CONFIG_X86
+#include <asm/physdev.h>
+#endif
+
 /* Config serial port with a string <baud>,DPS,<io-base>,<irq>. */
 static char opt_com1[30] = OPT_COM1_STR, opt_com2[30] = OPT_COM2_STR;
 string_param("com1", opt_com1);
@@ -482,10 +485,12 @@ void serial_force_unlock(int handle)
 
 void serial_endboot(void)
 {
+#ifdef CONFIG_X86
     int i;
     for ( i = 0; i < ARRAY_SIZE(com); i++ )
         if ( UART_ENABLED(&com[i]) )
             physdev_modify_ioport_access_range(dom0, 0, com[i].io_base, 8);
+#endif
 }
 
 /*
index 82608ac93f93f707376e70e08617d841a4c59b3f..719a68202eefae5c23d63dba3d6e349a8e8ddc23 100644 (file)
@@ -315,6 +315,4 @@ extern unsigned long xenheap_phys_end; /* user-configurable */
 #define ELFSIZE 32
 #endif
 
-#define __ARCH_HAS_IOAPIC
-
 #endif /* __X86_CONFIG_H__ */
diff --git a/xen/include/asm-x86/physdev.h b/xen/include/asm-x86/physdev.h
new file mode 100644 (file)
index 0000000..0b004d4
--- /dev/null
@@ -0,0 +1,17 @@
+/******************************************************************************
+ * physdev.h
+ */
+
+#ifndef __XEN_PHYSDEV_H__
+#define __XEN_PHYSDEV_H__
+
+#include <public/physdev.h>
+
+void physdev_modify_ioport_access_range(
+    struct domain *d, int enable, int port, int num );
+void physdev_destroy_state(struct domain *d);
+int domain_iomem_in_pfn(struct domain *p, unsigned long pfn);
+long do_physdev_op(physdev_op_t *uop);
+void physdev_init_dom0(struct domain *d);
+
+#endif /* __XEN_PHYSDEV_H__ */
index 828b00f9fe88ca982844d520022ca4be140d624a..869a959f6c72972d026dc4a8354031a893be5754 100644 (file)
@@ -208,19 +208,6 @@ typedef struct {
     memory_t free_pages;
 } dom0_physinfo_t;
 
-/* 
- * Allow a domain access to a physical PCI device
- */
-#define DOM0_PCIDEV_ACCESS    23
-typedef struct {
-    /* IN variables. */
-    domid_t      domain;
-    u32          bus;
-    u32          dev;
-    u32          func;
-    u32          enable;
-} dom0_pcidev_access_t;
-
 /*
  * Get the ID of the current scheduler.
  */
@@ -376,7 +363,6 @@ typedef struct {
         dom0_pincpudomain_t      pincpudomain;
         dom0_tbufcontrol_t       tbufcontrol;
         dom0_physinfo_t          physinfo;
-        dom0_pcidev_access_t     pcidev_access;
         dom0_sched_id_t          sched_id;
         dom0_shadow_control_t    shadow_control;
         dom0_setdomainmaxmem_t   setdomainmaxmem;
index b17f7d83c2b269319770b453ff00a4a09ef643ab..41ad23bb9fb834ff873be92d5ee967c1753639ff 100644 (file)
@@ -1,18 +1,8 @@
-/****************************************************************************
- * (c) 2004 - Rolf Neugebauer - Intel Research Cambridge
- * (c) 2004 - Keir Fraser - University of Cambridge
- ****************************************************************************
- * Description: Interface for domains to access physical devices on the PCI bus
- */
 
 #ifndef __XEN_PUBLIC_PHYSDEV_H__
 #define __XEN_PUBLIC_PHYSDEV_H__
 
 /* Commands to HYPERVISOR_physdev_op() */
-#define PHYSDEVOP_PCI_CFGREG_READ       0
-#define PHYSDEVOP_PCI_CFGREG_WRITE      1
-#define PHYSDEVOP_PCI_INITIALISE_DEVICE 2
-#define PHYSDEVOP_PCI_PROBE_ROOT_BUSES  3
 #define PHYSDEVOP_IRQ_UNMASK_NOTIFY     4
 #define PHYSDEVOP_IRQ_STATUS_QUERY      5
 #define PHYSDEVOP_SET_IOPL              6
 #define PHYSDEVOP_APIC_WRITE            9
 #define PHYSDEVOP_ASSIGN_VECTOR         10
 
-/* Read from PCI configuration space. */
-typedef struct {
-    /* IN */
-    u32 bus;                          /*  0 */
-    u32 dev;                          /*  4 */
-    u32 func;                         /*  8 */
-    u32 reg;                          /* 12 */
-    u32 len;                          /* 16 */
-    /* OUT */
-    u32 value;                        /* 20 */
-} PACKED physdevop_pci_cfgreg_read_t; /* 24 bytes */
-
-/* Write to PCI configuration space. */
-typedef struct {
-    /* IN */
-    u32 bus;                          /*  0 */
-    u32 dev;                          /*  4 */
-    u32 func;                         /*  8 */
-    u32 reg;                          /* 12 */
-    u32 len;                          /* 16 */
-    u32 value;                        /* 20 */
-} PACKED physdevop_pci_cfgreg_write_t; /* 24 bytes */
-
-/* Do final initialisation of a PCI device (e.g., last-moment IRQ routing). */
-typedef struct {
-    /* IN */
-    u32 bus;                          /*  0 */
-    u32 dev;                          /*  4 */
-    u32 func;                         /*  8 */
-} PACKED physdevop_pci_initialise_device_t; /* 12 bytes */
-
-/* Find the root buses for subsequent scanning. */
-typedef struct {
-    /* OUT */
-    u32 busmask[256/32];              /*  0 */
-} PACKED physdevop_pci_probe_root_buses_t; /* 32 bytes */
-
 typedef struct {
     /* IN */
     u32 irq;                          /*  0 */
@@ -85,7 +38,7 @@ typedef struct {
     u32 apic;                          /*  0 */
     u32 offset;
     /* IN or OUT */
-    u64 value;
+    u32 value;
 } PACKED physdevop_apic_t; 
 
 typedef struct {
@@ -100,12 +53,6 @@ typedef struct _physdev_op_st
     u32 cmd;                          /*  0 */
     u32 __pad;                        /*  4 */
     union {                           /*  8 */
-#ifdef CONFIG_PCI
-        physdevop_pci_cfgreg_read_t       pci_cfgreg_read;
-        physdevop_pci_cfgreg_write_t      pci_cfgreg_write;
-        physdevop_pci_initialise_device_t pci_initialise_device;
-        physdevop_pci_probe_root_buses_t  pci_probe_root_buses;
-#endif
         physdevop_irq_status_query_t      irq_status_query;
         physdevop_set_iopl_t              set_iopl;
         physdevop_set_iobitmap_t          set_iobitmap;
diff --git a/xen/include/xen/physdev.h b/xen/include/xen/physdev.h
deleted file mode 100644 (file)
index 9f1fc6c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/******************************************************************************
- * physdev.h
- */
-
-#ifndef __XEN_PHYSDEV_H__
-#define __XEN_PHYSDEV_H__
-
-#include <public/physdev.h>
-
-void physdev_modify_ioport_access_range(
-    struct domain *d, int enable, int port, int num );
-void physdev_destroy_state(struct domain *d);
-int physdev_pci_access_modify(
-    domid_t dom, int bus, int dev, int func, int enable);
-int domain_iomem_in_pfn(struct domain *p, unsigned long pfn);
-long do_physdev_op(physdev_op_t *uop);
-void physdev_init_dom0(struct domain *d);
-
-#endif /* __XEN_PHYSDEV_H__ */
index 37ab3ff744cad1c52b87be428c745286e74f3831..266e34e8ecabbdded2a1c1d8c7d709fa21892f97 100644 (file)
@@ -129,10 +129,6 @@ struct domain
     u16 pirq_to_evtchn[NR_PIRQS];
     u32 pirq_mask[NR_PIRQS/32];
 
-    /* Physical I/O */
-    spinlock_t       pcidev_lock;
-    struct list_head pcidev_list;
-
     unsigned long d_flags;
     unsigned long vm_assist;